package com.itheima.edu.info.manager.controller;

import com.itheima.edu.info.manager.domain.Option;
import com.itheima.edu.info.manager.domain.Student;
import org.apache.log4j.Logger;

import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;

public abstract class BaseStudentController {

    //创建键盘录入
    private Scanner sc = new Scanner(System.in);


    //创建日志对象
    private static final Logger LOGGER=Logger.getLogger(BaseStudentController.class);

    //创建一个集合接收学生对象
    ArrayList<Student> stus = new ArrayList<>();

    //开启学生管理系统，并展示学生管理系统菜单
    public final void start() {
        StudentLoop:
        while (true) {
            //主菜单搭建
            System.out.println("\r\n\t\t\t--------欢迎来到 <学生> 管理系统--------");
            System.out.println("请输入您的选择: 1.添加学生  2.删除学生  3.修改学生  4.查看学生  5.退出");
            String choice = sc.next();
            switch (choice) {
                case "1":
                    addStudent();
                    //  System.out.println("添加");
                    break;
                case "2":
                    deleteStudentById();
                    //   System.out.println("删除");
                    break;
                case "3":
                    updateStudentById();
                    //  System.out.println("修改");
                    break;
                case "4":
                    findAllStudent();
                    //    System.out.println("查看");
                    break;
                case "5":
                    System.out.println("感谢您的使用");
                    break StudentLoop;
                default:
                    System.out.println("您的输入有误，请重新输入");
                    break;
            }
        }

    }


    //客服的添加功能
    public final void addStudent() {
        //接收用户录入的学生学号
        String id = inputStudentId(false);
        //将录入的数据封装为学生对象
        Student stu = inputStudentinfo(id);
        //先假设添加不成功
        boolean res = false;

        try {
            //发生socket给服务器，在服务器端完成数据的添加
            Socket socket = getSocket();
            //请求服务器
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bw.write(Option.ADD_STUDENT + "&" + stu.toString());
            bw.newLine();
            bw.flush();

            //接收服务器响应的结果
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String result = br.readLine();

            if ("true".equals(result)) {
                res = true;
            }
        } catch (Exception e) {
            System.out.println("添加业务连接服务器异常");
        }
        //根据服务器的反馈，组织对应的输出信息给用户
        if (res) {
            System.out.println("添加成功");
            LOGGER.info("新增一名学生,学号为"+id);
        } else {
            System.out.println("添加失败");
        }


    }

    //客服的删除功能
    public final void deleteStudentById() {
        //调用优化方法：检验用户输入的学号是否存在，存在：可以继续，不存在：提示重试
        String delId = inputStudentId(true);
        //请求服务器去根据学号进行删除操作

        try {
            //发生socket给服务器，在服务器端完成数据的添加
            Socket socket = getSocket();
            //请求服务器
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bw.write(Option.DELETE_STUDENT_BY_ID + "&" + delId);
            bw.newLine();
            bw.flush();


        } catch (Exception e) {
            System.out.println("客户端删除功能异常");
        }

        //给出用户提示：删除成功
        System.out.println("删除成功");
        LOGGER.info("学号为："+delId+" 已被删除");
    }

    //客服的修改功能
    public final void updateStudentById() {
        //调用方法：输入学号id判断是否存在.  存在：继续执行  不存在：提示用户重新录入
        String updateId = inputStudentId(true);
        //调用方法：输入学生信息并封装为新的学生对象
        Student newStu = inputStudentinfo(updateId);
        //5.请求服务器进行修改业务，将要修改的学生学号和新的学生对象作为参数传递
        // service.updateStudentById(updateId, newStu);

        try {
            //发生socket给服务器，在服务器端完成数据的添加
            Socket socket = getSocket();
            //请求服务器
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bw.write(Option.UPDATE_STUDENT_BY_ID + "&" + newStu.toString());
            bw.newLine();
            bw.flush();


        } catch (Exception e) {
            System.out.println("客户端修改功能异常");
        }

        //6.给出修改成功的提示信息
        System.out.println("修改成功");
        LOGGER.info("学号为："+updateId+" 个人信息修改成功");
    }



    //客服的查看功能
    public final void findAllStudent() {
        //创建Socket对象
        //先假设接收的字符串数据为空
        String str1 = null;
        try {
            Socket socket = getSocket();
            //向服务器写数据
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //写数据
            bw.write(Option.FIND_STUDENT+"&");
            //换行
            bw.newLine();
            //刷新缓冲区
            bw.flush();
            //告诉服务器已经传输完成
            socket.shutdownOutput();

                //接收服务器反馈的信息
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //str1：读取服务端发送来的数据
            str1 = br.readLine();
        } catch (Exception e) {
            System.out.println("查看功能发送服务器异常");
        }


        //根据服务端返回的数据来组织对应的查看逻辑
        if (str1 == "") {
            System.out.println("无信息，请添加后重试");
        } else {
            //切割字符串获取学生对象字符串表现形式的数组
            String[] students = str1.split("=");
            System.out.println("学号\t\t姓名\t年龄\t生日");
            for (String student : students) {
                //切割生成学生对象
                String[] stus = student.split(",");
                //根据切割内容创建对象
                Student stu = new Student(stus[0], stus[1], stus[2], stus[3]);
                //打印数据(学生对象)
                System.out.println(stu.getId() + "\t" + stu.getName() + "\t" + stu.getAge() + "\t\t" + stu.getBirthday());
            }
        }

    }



    //输入学号id判断是否存在的优化方法
    public final String inputStudentId(boolean flag) {
        String id;
        while (true) {
            System.out.println("请输入学号：");
            id = sc.next();

            //标记位思想，先假设没有这个学号
            boolean exists = false;

            try {
                //获取socket对象
                Socket socket = getSocket();
                //请求服务器
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                bw.write(Option.IS_EXISTS_STUDENT + "&" + id);
                bw.newLine();
                bw.flush();

                //接收服务器响应的结果
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String res = br.readLine();
                //如果服务器返回结果为true，
                if ("true".equals(res)) {
                    //那么修改标记为true
                    exists = true;
                }

            } catch (Exception e) {
                System.out.println("输入学号id请求服务器判断出错");
            }


            if (exists == flag) {
                break;
            } else {
                System.out.println("当前学号不可用，请重新输入");
            }
        }
        return id;
    }

    //开闭原则：原代码不支持修改，但可以拿去扩展
    //输入学生信息并封装为学生对象的优化方法
    public abstract Student inputStudentinfo(String id);


    //登录
    public void login() {
        for (int i = 1; i <= 3; i++) {
            System.out.println("用户名");
            String username = sc.next();
            System.out.println("密码");
            String password = sc.next();
            //把判断的业务交给服务器处理
            try {
                //创建socket对象
                Socket socket = getSocket();
                //写入服务器,字符转字节
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                //传递业务的类型名称与用户名和密码
                bw.write(Option.LOGIN + "&" + username + "," + password);
                bw.newLine();
                bw.flush();
                //给服务器一个结束标记，告诉服务器文件已经上传成功
                socket.shutdownOutput();

                //接收服务器响应
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                //把读取的每行数据转为字符串
                String res = br.readLine();
                //关流
                socket.close();

                //解析结果
                if ("true".equals(res)) {
                    System.out.println("登录成功");
                    LOGGER.info("用户名为："+username+" 登录了系统");

                    break;
                } else {
                    if (i == 3) {
                        System.out.println("3次输错，下次重试");
                        System.exit(0);
                    } else {
                        System.out.println("登陆失败您还有" + (3 - i) + "次机会");
                    }

                }

            } catch (Exception e) {
                System.out.println("登录报错");
            }

        }


    }


    //封装一个方法，用于获取socket对象
    private Socket getSocket() throws IOException {
        return new Socket("127.0.0.1", 11);
    }








}
